/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package postmaster;

import MessageHandler.messagehandler;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.Timer;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author maniksin
 */
public class peer {
    // Addressing parameters
    private InetAddress ip;
    private int port;
    private String name;
    
    public peer_state state;
    public peer next_hop;
    
    public Timer hello_timer;
    public Timer neighbor_timer;
    
    Set clients;    // Set of clients waiting for this peer
    
    public peer(String name, peer next_hop, peer_state state) {
        
        this.name = name;
        this.next_hop = next_hop;
        this.state = state;
        
        neighbor_timer = new Timer();        
    }
    
    public peer(InetAddress ip, int port, String name, peer_state state) {
        this.ip = ip;
        this.port = port;
        this.state = state;
        this.name = name;
        
        clients = new HashSet();
        
        hello_timer = new Timer();
        neighbor_timer = new Timer();
        
        next_hop = null;    // adjacent peer
        
        //Logger.global.log(Level.INFO, "Created peer {0}", name);
    }
    
    public String get_name() {
        return name;
    }
    
    public static peer get_peer_by_dest_name(DatagramPacket dp, Set peers) {
        messagehandler msg = messagehandler.decode_message(dp);
        return get_peer_by_name(msg.dest, peers);
    }
    
    public static peer get_peer_by_source_name(DatagramPacket dp, Set peers) {
        messagehandler msg = messagehandler.decode_message(dp);
        return get_peer_by_name(msg.source, peers);
    }
    
    public static peer get_peer_by_name(String peer_name, Set peers) {
        peer next_peer;
        Iterator i = peers.iterator();
                
        while (i.hasNext()) {
            next_peer = (peer) i.next();
            if (next_peer.get_name().equals(peer_name)) {
                return next_peer;
            }
        }
        return null;
    }
    
    public peer(DatagramPacket dp, peer_state state) {
        this.ip = dp.getAddress();
        this.port = dp.getPort();
        this.state = state;
        
        messagehandler msg;
        msg = messagehandler.decode_message(dp);
        name = msg.source;
        
        hello_timer = new Timer();
        neighbor_timer = new Timer();
        
        Logger.global.log(Level.INFO, "Created peer {0}", name);
    }
        
    public InetAddress get_ip() {
        return ip;
    }
    
    public int get_port() {
        return port;
    }
    
    public void set_port(int port) {
        this.port = port;
    }
    
    public boolean matches(InetAddress ip, int port) {
        
        if (this.next_hop != null) {
            return false;   // non-adjacent peer. IP not known.
        }
        
        if (this.ip.equals(ip) && this.port == port) {
            return true;
        }
        
        return false;
    }
    

    
    public void remove(postmaster pm) {
        
        if (next_hop != null) {
            // non-adjacent peer
            neighbor_timer.cancel();
            pm.peers.remove(this);
            Logger.global.log(Level.INFO, "Monitoring stopped for peer {0}", name);
        } else if (ip.equals(pm.conf.server_ip) && port == pm.conf.server_port) {
            // We lost communication to our server
            // We need to stay alive and keep sending hellos
        } else {
            neighbor_timer.cancel();
            hello_timer.cancel();
            pm.peers.remove(this);
            Logger.global.log(Level.INFO, "Monitoring/hand-shaking stopped for peer {0}", name);
        }
        
    }

}
